#!/bin/bash
# 课程表管理系统 - 服务部署脚本
# 使用前提：代码已通过git更新到最新版本

echo "🚀 课程表管理系统 - 服务部署脚本"
echo "=================================================="

# 配置信息
PROJECT_ROOT="/home/reschedule_site"
BACKEND_DIR="$PROJECT_ROOT/backend"
FRONTEND_DIR="$PROJECT_ROOT/frontend/res_pro"
FRONTEND_BUILD_DIR="$FRONTEND_DIR/dist/build/h5"

# 日志文件
DEPLOY_LOG="/tmp/deploy-$(date +%Y%m%d_%H%M%S).log"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%H:%M:%S') - $1" | tee -a "$DEPLOY_LOG"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%H:%M:%S') - $1" | tee -a "$DEPLOY_LOG"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%H:%M:%S') - $1" | tee -a "$DEPLOY_LOG"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $(date '+%H:%M:%S') - $1" | tee -a "$DEPLOY_LOG"
}

# 检查必要目录
check_directories() {
    log_step "检查项目目录结构..."
    
    if [ ! -d "$PROJECT_ROOT" ]; then
        log_error "项目根目录不存在: $PROJECT_ROOT"
        exit 1
    fi
    
    if [ ! -d "$BACKEND_DIR" ]; then
        log_error "后端目录不存在: $BACKEND_DIR"
        exit 1
    fi
    
    if [ ! -d "$FRONTEND_DIR" ]; then
        log_error "前端目录不存在: $FRONTEND_DIR"
        exit 1
    fi
    
    log_info "✅ 目录结构检查通过"
}

# 停止现有服务
stop_services() {
    log_step "停止现有服务..."
    
    # 停止后端服务
    log_info "停止后端服务..."
    if pgrep -f "server" > /dev/null; then
        pkill -f "server"
        sleep 3
        
        # 强制停止（如果还在运行）
        if pgrep -f "server" > /dev/null; then
            log_warn "强制停止后端服务..."
            pkill -9 -f "server"
            sleep 2
        fi
        log_info "✅ 后端服务已停止"
    else
        log_info "后端服务未运行"
    fi
    
    # 停止前端服务
    log_info "停止前端服务..."
    if pgrep -f "python3 -m http.server 3000" > /dev/null; then
        pkill -f "python3 -m http.server 3000"
        sleep 2
        log_info "✅ 前端服务已停止"
    else
        log_info "前端服务未运行"
    fi
}

# 检查和配置Node.js环境
setup_nodejs_env() {
    log_step "检查Node.js环境..."
    
    # 检查Node.js版本
    if command -v node >/dev/null 2>&1; then
        NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
        log_info "Node.js版本: $(node --version)"
        
        if [ "$NODE_VERSION" -lt 16 ]; then
            log_error "Node.js版本过低，需要v16+，当前版本: $(node --version)"
            exit 1
        fi
    else
        log_error "Node.js未安装"
        exit 1
    fi
    
    # 检查npm
    if command -v npm >/dev/null 2>&1; then
        log_info "npm版本: $(npm --version)"
    else
        log_error "npm未安装"
        exit 1
    fi
    
    log_info "✅ Node.js环境检查通过"
}

# 检查Go环境
setup_go_env() {
    log_step "检查Go环境..."
    
    if command -v go >/dev/null 2>&1; then
        log_info "Go版本: $(go version)"
    else
        log_error "Go未安装"
        exit 1
    fi
    
    log_info "✅ Go环境检查通过"
}

# 配置前端环境和构建
setup_frontend() {
    log_step "配置前端环境..."
    
    cd "$FRONTEND_DIR" || exit 1
    
    # 检查package.json
    if [ ! -f "package.json" ]; then
        log_error "package.json不存在"
        exit 1
    fi
    
    # 智能依赖安装
    if [ ! -d "node_modules" ]; then
        log_info "首次安装依赖..."
        npm install
    elif [ "package.json" -nt "node_modules" ] || [ "package-lock.json" -nt "node_modules" ]; then
        log_info "依赖文件有更新，重新安装..."
        rm -rf node_modules package-lock.json
        npm install
    else
        log_info "依赖无变化，跳过安装"
    fi
    
    # 检查安装结果
    if [ $? -ne 0 ]; then
        log_error "依赖安装失败"
        exit 1
    fi
    
    log_info "✅ 前端依赖配置完成"
    
    # 构建前端
    log_step "构建前端项目..."
    npm run build:h5
    
    if [ $? -ne 0 ]; then
        log_error "前端构建失败"
        exit 1
    fi
    
    # 验证构建结果
    if [ ! -d "$FRONTEND_BUILD_DIR" ]; then
        log_error "前端构建目录不存在: $FRONTEND_BUILD_DIR"
        exit 1
    fi
    
    if [ ! -f "$FRONTEND_BUILD_DIR/index.html" ]; then
        log_error "前端构建结果异常，缺少index.html"
        exit 1
    fi
    
    log_info "✅ 前端构建完成"
}

# 构建后端
build_backend() {
    log_step "构建后端项目..."
    
    cd "$BACKEND_DIR" || exit 1
    
    # 检查go.mod
    if [ ! -f "go.mod" ]; then
        log_error "go.mod不存在"
        exit 1
    fi
    
    # 下载依赖
    log_info "下载Go依赖..."
    go mod tidy
    
    if [ $? -ne 0 ]; then
        log_error "Go依赖下载失败"
        exit 1
    fi
    
    # 构建项目
    log_info "编译后端项目..."
    go build -buildvcs=false -o server .
    
    if [ $? -ne 0 ]; then
        log_error "后端构建失败"
        exit 1
    fi
    
    # 验证构建结果
    if [ ! -f "server" ]; then
        log_error "后端可执行文件不存在"
        exit 1
    fi
    
    # 设置执行权限
    chmod +x server
    
    log_info "✅ 后端构建完成"
}

# 启动后端服务
start_backend() {
    log_step "启动后端服务..."
    
    cd "$BACKEND_DIR" || exit 1
    
    # 启动服务
    nohup ./server > server.log 2>&1 &
    BACKEND_PID=$!
    
    # 等待服务启动
    sleep 5
    
    # 验证服务启动
    if ps -p $BACKEND_PID > /dev/null 2>&1; then
        log_info "✅ 后端服务启动成功 (PID: $BACKEND_PID)"
        
        # 测试服务响应
        sleep 2
        HEALTH_CHECK=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:80/api/schedule/classes 2>/dev/null || echo "000")
        if [ "$HEALTH_CHECK" = "200" ] || [ "$HEALTH_CHECK" = "404" ]; then
            log_info "✅ 后端服务健康检查通过 (HTTP $HEALTH_CHECK)"
        else
            log_warn "⚠️  后端服务响应异常 (HTTP $HEALTH_CHECK)"
        fi
    else
        log_error "后端服务启动失败"
        log_error "错误日志:"
        tail -10 server.log
        exit 1
    fi
}

# 启动前端服务
start_frontend() {
    log_step "启动前端服务..."
    
    cd "$FRONTEND_BUILD_DIR" || exit 1
    
    # 启动前端服务
    nohup python3 -m http.server 3000 > frontend.log 2>&1 &
    FRONTEND_PID=$!
    
    # 等待服务启动
    sleep 3
    
    # 验证服务启动
    if ps -p $FRONTEND_PID > /dev/null 2>&1; then
        log_info "✅ 前端服务启动成功 (PID: $FRONTEND_PID)"
        
        # 测试服务响应
        sleep 2
        HEALTH_CHECK=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/ 2>/dev/null || echo "000")
        if [ "$HEALTH_CHECK" = "200" ]; then
            log_info "✅ 前端服务健康检查通过 (HTTP $HEALTH_CHECK)"
        else
            log_warn "⚠️  前端服务响应异常 (HTTP $HEALTH_CHECK)"
        fi
    else
        log_error "前端服务启动失败"
        log_error "错误日志:"
        tail -10 frontend.log
        exit 1
    fi
}

# 开放防火墙端口
setup_firewall() {
    log_step "配置防火墙..."
    
    # 开放必要端口
    sudo ufw allow 80 >/dev/null 2>&1 || true
    sudo ufw allow 3000 >/dev/null 2>&1 || true
    
    log_info "✅ 防火墙配置完成"
}

# 最终健康检查
final_health_check() {
    log_step "执行最终健康检查..."
    
    # 检查进程状态
    log_info "检查服务进程:"
    if pgrep -f "server" > /dev/null; then
        log_info "  ✅ 后端服务运行中 (PID: $(pgrep -f 'server'))"
    else
        log_error "  ❌ 后端服务未运行"
    fi
    
    if pgrep -f "python3 -m http.server 3000" > /dev/null; then
        log_info "  ✅ 前端服务运行中 (PID: $(pgrep -f 'python3 -m http.server 3000'))"
    else
        log_error "  ❌ 前端服务未运行"
    fi
    
    # 检查端口监听
    log_info "检查端口监听:"
    if netstat -tlnp 2>/dev/null | grep -q ":80 "; then
        log_info "  ✅ 端口80正在监听"
    else
        log_warn "  ⚠️  端口80未监听"
    fi
    
    if netstat -tlnp 2>/dev/null | grep -q ":3000 "; then
        log_info "  ✅ 端口3000正在监听"
    else
        log_warn "  ⚠️  端口3000未监听"
    fi
    
    # 外部访问测试
    log_info "测试外部访问:"
    FRONTEND_EXTERNAL=$(curl -s -o /dev/null -w "%{http_code}" http://47.108.201.156:3000/ 2>/dev/null || echo "000")
    BACKEND_EXTERNAL=$(curl -s -o /dev/null -w "%{http_code}" http://47.108.201.156/api/schedule/classes 2>/dev/null || echo "000")
    
    log_info "  前端外部访问: HTTP $FRONTEND_EXTERNAL"
    log_info "  后端外部访问: HTTP $BACKEND_EXTERNAL"
}

# 显示部署结果
show_deployment_result() {
    echo ""
    echo "=================================================="
    echo "🎉 部署完成！"
    echo "=================================================="
    echo "📅 部署时间: $(date)"
    echo "📝 部署日志: $DEPLOY_LOG"
    echo ""
    echo "🌐 访问地址:"
    echo "  前端: http://47.108.201.156:3000"
    echo "  后端: http://47.108.201.156:80"
    echo ""
    echo "🔧 管理命令:"
    echo "  查看后端日志: tail -f $BACKEND_DIR/server.log"
    echo "  查看前端日志: tail -f $FRONTEND_BUILD_DIR/frontend.log"
    echo "  停止后端: pkill -f server"
    echo "  停止前端: pkill -f 'python3 -m http.server 3000'"
    echo ""
    echo "📊 服务状态:"
    echo "  后端PID: $(pgrep -f 'server' || echo '未运行')"
    echo "  前端PID: $(pgrep -f 'python3 -m http.server 3000' || echo '未运行')"
    echo "=================================================="
}

# 错误处理函数
handle_error() {
    log_error "部署过程中发生错误，正在清理..."
    
    # 停止可能启动的服务
    pkill -f "server" 2>/dev/null || true
    pkill -f "python3 -m http.server 3000" 2>/dev/null || true
    
    echo ""
    echo "❌ 部署失败！"
    echo "📝 详细错误日志: $DEPLOY_LOG"
    echo "🔧 请检查错误信息并重新部署"
    
    exit 1
}

# 设置错误处理
trap handle_error ERR

# 主执行流程
main() {
    echo "📅 开始时间: $(date)"
    echo "📍 工作目录: $PROJECT_ROOT"
    echo "📝 日志文件: $DEPLOY_LOG"
    echo ""
    
    # 执行部署步骤
    check_directories
    setup_nodejs_env
    setup_go_env
    stop_services
    setup_frontend
    build_backend
    setup_firewall
    start_backend
    start_frontend
    final_health_check
    show_deployment_result
}

# 脚本参数处理
case "${1:-}" in
    "stop")
        log_info "仅停止服务..."
        stop_services
        log_info "✅ 所有服务已停止"
        ;;
    "start")
        log_info "仅启动服务..."
        start_backend
        start_frontend
        final_health_check
        log_info "✅ 所有服务已启动"
        ;;
    "restart")
        log_info "重启服务..."
        stop_services
        sleep 2
        start_backend
        start_frontend
        final_health_check
        log_info "✅ 服务重启完成"
        ;;
    "status")
        log_info "检查服务状态..."
        final_health_check
        ;;
    *)
        # 完整部署流程
        main
        ;;
esac
